home *** CD-ROM | disk | FTP | other *** search
- /*
- * List abstract class
- *
- * Copyright © John Wainwright 1988
- *
- * head l - returns first item in list l
- * tail l - returns list l minus 1st item
- * append l item - appends item to list l
- * push l item - pushes item on front of l
- * join l1 l2 - joins list2 to end of list1
- * isEmpty l - returns non-zero if list is empty, ,zero if not
- * eq l1 l2 - test isomorphic equality between l1 & l2
- * new l itemlist - builds new list
- * add l itemList - adds items to list
- * nth i l - nth item in list
- * second l - second item in list
- * third l - third item in list
- * sequence l - returns an initialised sequence object containing l
- * map l f - maps function over each element of l
- * copy l - returns a new list which is a copy of l
- * deepCopy l - returns a deep copy of l
- * dispose l - disposes the list structure l (but not the items)
- * deepDispose l - dispose l and sends 'deepDispose' to all it contains
- * print l - outputs nicely formatted list l to stdout
- * repList l - returns a representation (ascii) list for l
- */
-
- #include "oic.h"
- #include "generics.h"
-
- class List; /* the list class */
-
- typedef struct /* list instance structure */
- {
- list l_next;
- object l_item;
- } list_i;
-
- /* -------------------- List Instance methods ---------------------------- */
-
- static list
- _new(self, l, items)
- object self;
- register list_i *l;
- register object *items;
- {
- while (*items != END)
- append(self, *items++);
-
- return Super(self);
- }
-
- static object
- _head(self, list)
- object self;
- register list_i *list;
- {
- return list->l_item;
- }
-
- static list
- _tail(self, list)
- object self;
- register list_i *list;
- {
- return (list->l_item == END) ? self : list->l_next;
- }
-
- static list
- _append(self, l, item)
- object self;
- register list_i *l;
- object *item;
- {
- register list_i *li;
-
- for (li = l; li->l_item != END; li = localIVs(li->l_next, list_i));
- li->l_next = New(List, END);
- li->l_item = *item;
-
- return self;
- }
-
- static list
- _join(self, l, list2)
- object self;
- register list_i *l;
- object *list2;
- {
- register list_i *l1, *l2;
-
- l2 = localIVs(*list2, list_i);
- for (l1 = l; l1->l_item != END; l1 = localIVs(l1->l_next, list_i));
- l1->l_next = l2->l_next;
- l1->l_item = l2->l_item;
-
- return self;
- }
-
- static list
- _push(self, l, item)
- object self;
- register list_i *l;
- object *item;
- {
- register list newl;
- register list_i *newinst;
-
- newl = New(List, END);
- newinst = localIVs(newl, list_i);
- newinst->l_next = l->l_next;
- newinst->l_item = l->l_item;
- l->l_next = newl;
- l->l_item = *item;
-
- return self;
- }
-
- static int
- _isEmpty(self, l)
- object self;
- register list_i *l;
- {
- return (l->l_item == END);
- }
-
- static int
- _eq(self, l, otherlist)
- object self;
- list_i *l;
- list *otherlist;
- {
- register object head1, head2;
-
- head1 = head(self);
- head2 = head(*otherlist);
-
- if (head1 == END && head2 == END)
- return 1;
- if (head1 == END || head2 == END)
- return 0;
- if ((int)eq(head1, head2))
- return ((int)eq(tail(self), tail(*otherlist)));
- else
- return 0;
- }
-
- static list
- _add(self, l, items)
- object self;
- register list_i *l;
- register object *items;
- {
- while (*items != END)
- append(self, *items++);
-
- return self;
- }
-
- static object
- _sequence(self)
- object self;
- {
- return start(New(Linkseq), self);
- }
-
- static object
- _assoc(self, l, key)
- object self;
- register list_i *l;
- object *key;
- {
- register list_i *lp;
-
- for (lp = l; lp->l_item != END; lp = localIVs(lp->l_next, list_i))
- if (ClassOf(lp->l_item) == List && eq(head(lp->l_item), *key))
- return head(tail(lp->l_item));
-
- return END;
- }
-
- static object
- _nth(self, l, n)
- object self;
- register list_i *l;
- int *n;
- {
- register list_i *lp;
- register int i;
-
- for (lp = l, i = 0; i < *n && lp->l_item != END; i++, lp = localIVs(lp->l_next, list_i))
- ;
-
- return lp->l_item;
- }
-
- static object
- _second(self)
- object self;
- {
- return head(tail(self));
- }
-
- static object
- _third(self)
- object self;
- {
- return head(tail(tail(self)));
- }
-
- static object
- _repList(self, l, ap)
- object self;
- list_i *l;
- void *ap;
- {
- register list_i *lp;
- register object replist;
-
- replist = New(Replist, "(", ")", " ");
- if (l->l_item == END)
- append(replist, New(String, "EMPTY"));
- else
- {
- for (lp = l; lp->l_item != END; lp = localIVs(lp->l_next, list_i))
- append(replist, repList(lp->l_item));
- }
-
- return replist;
- }
-
- static
- _deepDispose(self, li, ap)
- object self;
- register list_i *li;
- void *ap;
- {
- register object lo, nextl;
-
- if (li->l_item != END)
- {
- deepDispose(li->l_item);
- for (lo = li->l_next; (li = (localIVs(lo, list_i)))->l_item != END; lo = nextl)
- {
- nextl = li->l_next;
- deepDispose(li->l_item);
- free(lo);
- }
- }
-
- free(self);
- }
-
- static
- _dispose(self, li)
- object self;
- register list_i *li;
- {
- register object lo, nextl;
-
- if (li->l_item != END)
- {
- for (lo = li->l_next; (li = (localIVs(lo, list_i)))->l_item != END; lo = nextl)
- {
- nextl = li->l_next;
- free(lo);
- }
- }
-
- free(self);
- }
-
- /* ------------------- Init the List class ------------------------------- */
-
- _InitList()
- {
- List = NewClass(sizeof(list_i), 0, "List", END);
- AddMethods(List,
- appendGeneric, _append,
- joinGeneric, _join,
- pushGeneric, _push,
- headGeneric, _head,
- tailGeneric, _tail,
- assocGeneric, _assoc,
- nthGeneric, _nth,
- secondGeneric, _second,
- thirdGeneric, _third,
- isEmptyGeneric, _isEmpty,
- eqGeneric, _eq,
- sequenceGeneric, _sequence,
- disposeGeneric, _dispose,
- deepDisposeGeneric, _deepDispose,
- newGeneric, _new,
- addGeneric, _add,
- repListGeneric, _repList,
- END);
- }
-
-